#!/usr/bin/env python
# encoding: utf-8
# @author: Lin Han
# @contact: voldemort22@126.com
# @file: deprecated_app.py
# @time: 2021/3/23 16:59
# @desc:
import json
import os

from fastapi import APIRouter, BackgroundTasks

from application.history_part.crud import keyword_search_history_part, generate_history_part_data, take_out_part_type_recursively
from application.history_part.queryModel import UploadHistoryPartModel, HistoryPartImageModel, UploadHistoryPartModelForWPF, ListUploadHistoryPartModelForWPF
from background.background_update import update_02
from cache.redis_pool import get_redis
from models.models import PartTag
from models.queryModels import MultipleConditionQueryHistoryParts, UpdateHistoryPartConfigData, LockFlagQuery
from utils.mongo_tools import create_one_mongo_value, delete_mongo_value, retrieve_one_mongo_value, retrieve_all_mongo_values, update_mongo_value, history_part_number_generator
from views.configs import *
from views.configs import HISTORY_PART_COLLECTION
from views.crud import separate_page, send_to_message_queue, sort_redis_result

history_part_router = APIRouter(
    prefix="/api/history_part",
    tags=["history_part"],
)


@history_part_router.get("/v1/history_part_gltf_file")
def get_history_part_gltf_file(number: str):
    """
    返回历史零件的gltf模型在OSS上的地址

    - :param number:
    - :return:
    """
    model = {"data": ""}
    original_data = retrieve_one_mongo_value(
        number=number,
        collection_name=HISTORY_PART_COLLECTION
    )
    try:
        model["data"] = original_data[0]["file"][GLTF_OSS_ADDRESS]
    except:
        model["status"] = 0
    model["status"] = 1
    return model


@history_part_router.get("/v1/history_part_catia_file")
def get_history_part_catia_file(number: str):
    """
    返回之前上传的历史零件的catia格式文件（oss地址）。

    - :param number:
    - :return:
    """
    model = {"data": ""}
    original_data = retrieve_one_mongo_value(
        number=number,
        collection_name=HISTORY_PART_COLLECTION,
    )
    try:
        model["data"] = {
            "name": original_data[0]['name'],
            "path": original_data[0]["file"][CATPART_OSS_ADDRESS],
        }
    except:
        model["status"] = 0
    model["status"] = 1
    return model


@history_part_router.put("/v2/history_part_flag_tag")
def update_history_part_flag_tag_v2(queryModel: LockFlagQuery):
    """
    锁定零件状态

    - :param number:
    - :param isFlag:
    - :return:
    """
    redis_connection = get_redis(port=HISTORY_PART_REDIS_PORT)
    try:
        history_part = redis_connection.get(queryModel.number)
        history_part = json.loads(history_part)
    except:
        history_part = retrieve_all_mongo_values({"number": queryModel.number}, collection_name=HISTORY_PART_COLLECTION)[0]
        if "partTypeName" in history_part["tag"].keys() and history_part["tag"]["partTypeName"] != "":
            part_type = retrieve_all_mongo_values({}, collection_name=PART_TYPE_COLLECTION)
            part_type_dict = {i["number"]: i["name"] for i in part_type}
            part_type_parent_dict = {i["number"]: i["parent"] for i in part_type}
            try:
                history_part["tag"]["partTypeName"] = part_type_dict[history_part["tag"]["partType"]]
                history_part["tag"]["partTypeParent"] = part_type_dict[part_type_parent_dict[history_part["tag"]["partType"]]]
            except:
                pass

    history_part["isFlag"] = queryModel.isFlag
    update_mongo_value(
        filter_condition={"number": queryModel.number},
        new_value={"$set": {"isFlag": queryModel.isFlag}},
        collection_name=HISTORY_PART_COLLECTION,
    )
    try:
        redis_connection.set(queryModel.number, json.dumps(history_part))
    except:
        pass

    model = {
        "status": 1,
        "data": True,
    }
    return model


@history_part_router.post("/v3/history_parts")
def multiple_condition_query_history_parts_v3(queryModel: MultipleConditionQueryHistoryParts, background_tasks: BackgroundTasks):
    """
    ## 列表查询多条历史零件v3
    输入参数所有字段均可为空。

    - :param queryModel:
    - :return:
    """
    redis_connection = get_redis(port=HISTORY_PART_REDIS_PORT)
    model = {"data": {"result": []}}

    # 先把redis中的符合历史夹具的key都拿出来
    try:
        history_part_number_list = redis_connection.get("history_part")
        history_part_number_list = json.loads(history_part_number_list)
        history_part = redis_connection.mget(*history_part_number_list)
        result = [json.loads(i) for i in history_part]
    except:
        result = retrieve_all_mongo_values({}, collection_name=HISTORY_PART_COLLECTION)
        background_tasks.add_task(update_02)

    # if queryModel.partType is not None and len(queryModel.partType) > 0:
    #     take_out_part_type_recursively(queryModel.partType[0], queryModel.partType)

    result = keyword_search_history_part(queryModel, result)

    model["data"]["total"] = len(result)
    if len(result) > 0:
        if not queryModel.isTotal:
            model["data"]["result"] = separate_page(result, page=queryModel.page, pagesize=queryModel.pagesize)
        else:
            model["data"]["result"] = result
    model["status"] = 1
    return model


@history_part_router.get("/v3/history_part_config")
def retrieve_history_part_config_v3():
    """
    ## 获取历史零件config标签属性v2版

    - :return:
    """
    redis_connection = get_redis(port=HISTORY_PART_REDIS_PORT)
    try:
        history_part_config = redis_connection.get("history_part_config")
        history_part_config = json.loads(history_part_config)
    except:
        history_part_config = retrieve_all_mongo_values({"type": CONFIG_DATA_HISTORY_PART_TYPE}, collection_name=CONFIG_COLLECTION)[0][CONFIG_DATA]
        # 这个可以考虑把它作成background_tasks
        redis_connection.set("history_part_config", json.dumps(history_part_config))

    model = {"data": history_part_config, "status": 1}
    return model


@history_part_router.put("/v3/history_part_config")
def update_history_part_config_v3(oneInfo: UpdateHistoryPartConfigData):
    """
    ## 修改历史零件config标签属性v3版

    - :return:
    """
    redis_connection = get_redis(port=HISTORY_PART_REDIS_PORT)
    config_data = retrieve_all_mongo_values(
        {"type": CONFIG_DATA_HISTORY_PART_TYPE},
        collection_name=CONFIG_COLLECTION
    )[0][CONFIG_DATA]
    if oneInfo.standard is not None:
        config_data['standard'] = oneInfo.standard
    if oneInfo.partType is not None:
        config_data['partType'] = oneInfo.partType
    if oneInfo.version is not None:
        config_data['version'] = oneInfo.version
    updateInfo = {"$set": {"configData": config_data}}
    update_mongo_value(
        filter_condition={"type": CONFIG_DATA_HISTORY_PART_TYPE},
        new_value=updateInfo,
        collection_name=CONFIG_COLLECTION,
    )
    config_data = retrieve_all_mongo_values({"type": CONFIG_DATA_HISTORY_PART_TYPE}, collection_name=CONFIG_COLLECTION)[0][CONFIG_DATA]
    redis_connection.set("history_part_config", json.dumps(config_data))
    model = {"data": True, "status": 1}
    return model


@history_part_router.put("/v2/history_part_image")
def update_history_part_image_v2(queryModel: HistoryPartImageModel):
    """
    ## 添加/更新历史零件缩略图v2

    - :return:
    """
    redis_connection = get_redis(port=HISTORY_PART_REDIS_PORT)
    history_part = retrieve_one_mongo_value(queryModel.number, collection_name=HISTORY_PART_COLLECTION)[0]
    history_part["imgUrl"] = queryModel.imgUrl
    updateInfo = {"$set": history_part}
    update_mongo_value(
        filter_condition={"number": queryModel.number},
        new_value=updateInfo,
        collection_name=HISTORY_PART_COLLECTION,
    )
    redis_connection.set(queryModel.number, json.dumps(history_part))
    model = {"data": True, "status": 1}
    return model


@history_part_router.put("/v3/history_part")
def update_history_part_v3(queryModel: PartTag):
    """
    ## 修改历史零件标签属性

    - :param queryModel: 要更新的零件的信息
    - :return:
    """
    redis_connection = get_redis(port=HISTORY_PART_REDIS_PORT)

    history_part = retrieve_all_mongo_values(
        {"number": queryModel.number},
        collection_name=HISTORY_PART_COLLECTION,
    )[0]
    if queryModel.partType is not None:
        history_part['tag']['partType'] = queryModel.partType
    if queryModel.version is not None:
        history_part['tag']['version'] = queryModel.version
    if queryModel.standard is not None:
        history_part['tag']['standard'] = queryModel.standard
    if queryModel.jsonAliOssAddress is not None:
        history_part['file']['jsonAliOssAddress'] = queryModel.jsonAliOssAddress
    updateInfo = {"$set": history_part}
    update_mongo_value(
        {"number": queryModel.number},
        updateInfo,
        collection_name=HISTORY_PART_COLLECTION,
    )

    part_type = retrieve_all_mongo_values({}, collection_name=PART_TYPE_COLLECTION)

    redis_connection.set(queryModel.number, json.dumps(history_part))

    model = {"data": True, "status": 1}
    return model


@history_part_router.delete("/v2/history_part")
def delete_history_part_v2(number: str, background_task: BackgroundTasks):
    """
    ## 根据零件的编号删除历史零件
    一次删除单条数据，v2版

    - :param number:
    - :return:
    """
    model = {"data": False}
    try:
        result = delete_mongo_value(number, collection_name=HISTORY_PART_COLLECTION)
        background_task.add_task(update_02)
        if result.deleted_count > 0:
            model["data"] = True
            model["status"] = 1
        else:
            model["status"] = 0
    except:
        model["status"] = 0
    return model


@history_part_router.post("/v4/history_part")
def upload_v4(queryModel: UploadHistoryPartModel, background_task: BackgroundTasks):
    """
    ## 上传历史零件
    json的上传是有点问题的。

    - :return:
    """
    redis_connection = get_redis(port=HISTORY_PART_REDIS_PORT)
    data = []
    for i in queryModel.catpartAliOssAddress:
        json_path = i.replace(".CATPart", ".json5")
        number = history_part_number_generator()
        partModel = generate_history_part_data(
            number,
            file_path=i,
            json_path=json_path,
            version=queryModel.version,
        )
        if queryModel.standard is not None:
            partModel["tag"]["standard"] = queryModel.standard

        redis_connection.set(partModel["number"], json.dumps(partModel))

        create_one_mongo_value(partModel, collection_name=HISTORY_PART_COLLECTION)
        send_to_message_queue(number)
        data.append(number)

    background_task.add_task(update_02)
    model = {"data": data, "status": 1}
    return model


@history_part_router.get("/v2/history_part")
def retrieve_history_part_v2(number: str):
    """
    返回一条历史零件的完整信息

    - :param number: 编号
    - :return:
    """
    redis_connection = get_redis(port=HISTORY_PART_REDIS_PORT)
    model = {"data": {}}

    # take out the data in redis
    try:
        try:
            history_part = redis_connection.get(number)
            data = json.loads(history_part)
        except:
            # if reach here then means no data in redis. Now go to mongo.
            data = retrieve_one_mongo_value(number, collection_name=HISTORY_PART_COLLECTION)[0]
            # then add it into redis
            redis_connection.set(number, json.dumps(data))
            history_part_number_list = redis_connection.get("history_part")
            history_part_number_list = json.loads(history_part_number_list)
            history_part_number_list.append(number)
            redis_connection.set("history_part", json.dumps(history_part_number_list))
        model["data"] = data

        sort_redis_result(model=model, number=number, data_type="history_part", redis_connection=redis_connection)

        model["status"] = 1
    except:
        model["status"] = 0
    return model


@history_part_router.get("/v1/part_type")
def retrieve_history_part_part_type():
    """
    查询全部part_type

    - :param number: 编号
    - :return:
    """
    model = {}
    try:
        data = retrieve_all_mongo_values(
            {},
            collection_name=PART_TYPE_COLLECTION,
        )

        model["status"] = 1
        model["data"] = data
    except:
        model["data"] = {}
        model["status"] = 0
    return model


@history_part_router.post("/v5/history_part")
def upload_v5(queryModel: UploadHistoryPartModelForWPF, background_task: BackgroundTasks):
    """
    ## 上传历史零件
    json的上传是有点问题的。

    - :return:
    """
    redis_connection = get_redis(port=HISTORY_PART_REDIS_PORT)
    number = history_part_number_generator()
    partModel = generate_history_part_data(
        number,
        file_path=queryModel.catpartAliOssAddress,
        json_path=queryModel.jsonAliOssAddress,
    )
    if queryModel.standard is not None:
        partModel["tag"]["standard"].append(queryModel.standard)
    if queryModel.version is not None:
        partModel["version"] = queryModel.version
    if queryModel.partType is not None:
        partModel["tag"]["partType"] = queryModel.partType
    if queryModel.imgUrl is not None:
        partModel["imgUrl"] = queryModel.imgUrl

    redis_connection.set(partModel["number"], json.dumps(partModel))

    create_one_mongo_value(partModel, collection_name=HISTORY_PART_COLLECTION)
    send_to_message_queue(number)

    background_task.add_task(update_02)
    model = {"data": number, "status": 1}
    return model


@history_part_router.post("/v6/history_part")
def upload_v6(queryModel: ListUploadHistoryPartModelForWPF, background_task: BackgroundTasks):
    """
    ## 上传历史零件
    json的上传是有点问题的。

    - :return:
    """
    redis_connection = get_redis(port=HISTORY_PART_REDIS_PORT)
    data = []
    for i, j in zip(queryModel.catpartAliOssAddress, queryModel.jsonAliOssAddress):
        # json_path = i.replace(".CATPart", ".json5")
        number = history_part_number_generator()
        partModel = generate_history_part_data(
            number,
            file_path=i,
            json_path=j,
            version=queryModel.version,
        )
        if queryModel.standard is not None:
            partModel["tag"]["standard"].append(queryModel.standard)
        if queryModel.version is not None:
            partModel["version"] = queryModel.version
        if queryModel.partType is not None:
            partModel["tag"]["partType"] = queryModel.partType

        redis_connection.set(partModel["number"], json.dumps(partModel))

        create_one_mongo_value(partModel, collection_name=HISTORY_PART_COLLECTION)
        send_to_message_queue(number)
        data.append(number)

    background_task.add_task(update_02)
    model = {"data": data, "status": 1}
    return model
